package com.pf.aop;

import com.pf.utils.AESUtils;
import com.pf.utils.ERSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;

/**
 * @author PanFei
 * @date 2021/9/9
 * @Version 1.0
 */
@Aspect
@Component
@Slf4j
public class DecryptAspect {

    @Pointcut("@annotation(com.pf.aop.DecryptMethod)")
    public void pointcut() {
    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println(">>>>>>>>>>>before");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String contentType = request.getContentType();
        try {
            // json请求
            if (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
                Object paramObj = joinPoint.getArgs()[0];
                String serectKeyValue = null;
                Field[] fields = paramObj.getClass().getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    // 获取密钥key的字段值
                    if (field.isAnnotationPresent(EncryptSecretKey.class) && field.getType().equals(String.class)) {
                        serectKeyValue = (String) ReflectionUtils.getField(field, paramObj);
                    }
                    if (field.isAnnotationPresent(EncryptField.class) && field.getType().equals(String.class)) {
                        String fieldValue = (String) ReflectionUtils.getField(field, paramObj);
                        String aesKey = ERSAUtils.decrypt(serectKeyValue, ERSAUtils.getPrivateKey(ERSAUtils.PRIVATE_KEY));
                        fieldValue = AESUtils.decrypt(fieldValue, aesKey);
                        ReflectionUtils.setField(field, paramObj, fieldValue);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 环绕通知也可以
     */
   /* @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String contentType = request.getContentType();

        // json请求
        if (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
            Object paramObj = joinPoint.getArgs()[0];
            Field[] fields = paramObj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(EncryptField.class) && field.getType().equals(String.class)) {
                    String fieldValue = (String) ReflectionUtils.getField(field, paramObj);
                    ReflectionUtils.setField(field, paramObj, RsaUtils.decrypt(fieldValue));
                }
            }
        }
        return joinPoint.proceed();
    }*/
}
